package com.java7;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.atomic.LongAdder;

/**
 * @Description 1-10累加
 * @Author zhouhai
 * @Date2018/9/711:17
 **/
public class ForkJoinDemo2 {

    public static void main(String[] args) {
        //并行: 多核心参与
        //并发:一同参与
        //ForkJoin 线程池:ForkJoinPool
        System.out.printf("当前公用ForkJoin 线程池 并行数:%d\n", ForkJoinPool.commonPool().getParallelism());
        System.out.printf("当前CPU处理器数:%d\n", Runtime.getRuntime().availableProcessors());
        //与ThreadPoolExecutor类似
        ForkJoinPool forkJoinPool = new ForkJoinPool();

        List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        //累加对象
        LongAdder longAdder = new LongAdder();
        //ResucsiveAction 递归操作
        AddTask addTask = new AddTask(nums, longAdder);

        forkJoinPool.invoke(addTask);

        forkJoinPool.shutdown();

        System.out.println(longAdder);
    }

    private static class AddTask extends RecursiveAction {

        private final List<Integer> nums;

        private final LongAdder longAdder;


        private AddTask(List<Integer> nums, LongAdder longAdder) {
            this.nums = nums;
            this.longAdder = longAdder;
        }

        @Override
        protected void compute() {
            int size = nums.size();

            if (size > 1) {
                //二分部分数
                int parts = size / 2;
                //上半部
                List<Integer> leftPart = nums.subList(0, parts);
                AddTask leftTask = new AddTask(leftPart, longAdder);
                //下半部
                List<Integer> rightPart = nums.subList(parts, size);
                AddTask rightTask = new AddTask(rightPart, longAdder);
                //fork/join
                invokeAll(leftTask, rightTask);

            } else { //当前的元素只有一个
                if (size == 0) {
                    return;
                }
                Integer value = nums.get(0);
                //累加
                longAdder.add(value.intValue());
            }
        }
    }


}
